home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / DCLAP 4j / Drtf / DRichProcess.cpp < prev    next >
Encoding:
Text File  |  1995-12-17  |  9.3 KB  |  461 lines  |  [TEXT/R*ch]

  1. // DRichProcess.cpp
  2. // d.g.gilbert
  3.  
  4.  
  5. #include "Dvibrant.h"
  6. #include "DFile.h"
  7. #include "DRichProcess.h"
  8. #include "DRichViewNu.h"
  9.  
  10. #define rtfmapInternal
  11. #include "rtfmaps.h"
  12. #undef rtfmapInternal
  13.  
  14.  
  15. // struct StyleRec
  16.  
  17. //static DParagraph     gDefParaFmt;
  18. static StyleRec         gDefaultStyle;
  19. static Nlm_Uint4         gLinkcolor;
  20.  
  21. static char        *kDefaultFontname   = "Courier"; //"Times";
  22. static char        *kDefaultFontfamily = "Modern"; //"Roman";    
  23.  
  24.  
  25. StyleRec::StyleRec()
  26. {
  27.     style = DRichStyle();  // DRichStyle constructor handles !?
  28.     fontname= kDefaultFontname;
  29.     fontfamily= kDefaultFontfamily;
  30.     fontsize= DRichprocess::kDefaultFontsize;
  31. }
  32.  
  33.     
  34.     
  35. DRichprocess::DRichprocess( DFile* itsFile, DRichView* itsDoc, Nlm_MonitorPtr progress) :
  36.     fClass(tokUnknown), fMajor(0), fMinor(0), fParam(0),
  37.     fDataFile( itsFile), fDataBuffer( NULL), fDataSize(0), 
  38.     fDoc(itsDoc), fProgress(progress), fParaCount(0),
  39.     fText(NULL), fTextSize(0), fLastTextSize(0), fTextMax(0),
  40.     fLastChar(0), fPushedChar(EOF), fOutMap(NULL),
  41.     fStyleStackSize(0), fTitle(NULL), fNewStyle(true),
  42.     fEndOfData(false)
  43.     fTextMax= 1024;
  44.     fText= (char*) MemNew(fTextMax+1);
  45.  
  46.     fStyleMax= 5;
  47.     fStyleCount= 0;
  48.     fStyleArray= (DRichStyle*) Nlm_MemNew( fStyleMax*sizeof(DRichStyle));
  49.     fStyleStackSize= 0;
  50.  
  51. #if 0
  52.     fStyleRec.style = DRichStyle();
  53.             // don't need this jazz, constructors handle it
  54.     //DRichStyle    aStyle(false);
  55.     //fStyleRec.style= aStyle;
  56.     //fStyleRec.fontname= kDefaultFontname;
  57.     //fStyleRec.fontfamily= kDefaultFontfamily;
  58.     //fStyleRec.fontsize= kDefaultFontsize;
  59. #endif
  60.     fOldStyleRec= fStyleRec;
  61.     gDefaultStyle= fStyleRec;
  62.     
  63.     (void) GetNlmFont();
  64.     
  65.     // !?? static constructors for DParagraph should do all these !?
  66.     // fParaFmt = DParagraph();
  67.     fParaFmt.deftabstop = kDefTabstop;
  68.     // !?? static constructors for DParagraph should do all these !?
  69.     fOldParaFmt= fParaFmt;
  70.     fDefParaFmt= fParaFmt;
  71.  
  72.         // not for text types ?? (RTF should be ok w/ this...)
  73.     if (fDataFile) {
  74.         ulong fileindex;
  75.         fDataFile->GetDataMark( fileindex);
  76.         fDataFile->Open("rb"); // !!!!! DAMN TEXT TRANSLATION (0d to 0a) WAS SCREWING US UP !!
  77.         fDataFile->SetDataMark( fileindex);
  78.         }
  79. }
  80.  
  81.     
  82. DRichprocess::~DRichprocess()
  83. {
  84.     Close();
  85.     //if (fDataFile) fDataFile->Close(); // caller may do this?
  86.     MemFree(fText);
  87.     MemFree(fStyleArray);
  88.     MemFree(fTitle);
  89.     
  90. }
  91.  
  92. void DRichprocess::SetBuffer( char* dataBuffer, ulong dataSize, Boolean endOfData)
  93. {
  94.     fDataSize= dataSize;
  95.     if (dataSize) fDataBuffer= dataBuffer;
  96.     else fDataBuffer= NULL; // prevent GetOneChar trying to read when no data !
  97.     fEndOfData= endOfData;
  98. }
  99.  
  100. void DRichprocess::Read()
  101. {
  102.     while (GetToken() != tokEOF) 
  103.         RouteToken();
  104.     Close();
  105. }
  106.  
  107. void DRichprocess::Close()
  108. {
  109.     if (fTextSize>0) {
  110.         PutLitCharWithStyle('\n');
  111.         NewParagraph(); /* push last text into doc */
  112.         }
  113.     if (fProgress && fDataFile) {
  114.         long fat= fDataFile->Tell();
  115.         if (fat>0) (void) Nlm_MonitorIntValue(fProgress, fat);
  116.         }
  117. }
  118.  
  119.  
  120. short DRichprocess::GetOneChar()
  121. {
  122.     short    c;
  123.  
  124.     if (fDataBuffer) {
  125.         c= (unsigned char) *fDataBuffer; // must be unsigned !!
  126.         if (fDataSize) {    // for counted data
  127.             fDataSize--;
  128.             fDataBuffer++;
  129.             if (!fDataSize) fDataBuffer= NULL; //  so EOF next time
  130.             }
  131.         else if (c) fDataBuffer++; // for null-term data
  132.         else if (!fEndOfData) c= tokBreakInData;
  133.         else c= EOF;
  134.         }
  135.     else if (fDataFile) 
  136.         c = fgetc( fDataFile->fFile);
  137.     else {
  138.         if (!fEndOfData) c= tokBreakInData;
  139.         else c= EOF;
  140.         }
  141.     return (c);
  142. }
  143.  
  144.  
  145. void DRichprocess::Pushback(char c) // private
  146. {
  147.     if (c != EOF) {
  148.         fPushedChar = c;
  149.         }
  150. }
  151.  
  152.  
  153. void DRichprocess::RouteToken()
  154. {
  155.     switch( fClass ) {
  156.         case tokUnknown:  
  157.             handleUnknownClass(); 
  158.             break;
  159.         case tokText: 
  160.             handleTextClass(); 
  161.             break;
  162.         case tokControl:  
  163.             handleControlClass(); 
  164.             break;
  165.         default:
  166.             //RTFPanic ("Unknown class %d: %s ", fClass, fTokenBuf);
  167.             break;
  168.         }    
  169. }
  170.  
  171. short DRichprocess::GetToken()
  172. {
  173.     do GetToken1(); 
  174.     while (fClass == tokDropchar);
  175.     return (fClass);
  176. }
  177.  
  178.  
  179. void DRichprocess::GetToken1() // private
  180. {
  181.     short    c;
  182.     
  183.         /* initialize token vars */
  184.     fClass = tokUnknown;
  185.     fParam = tokNoParam;
  186.  
  187.         /* get first token character, which may be a pushback from previous token */
  188.     if (fPushedChar != EOF) {
  189.         c = fPushedChar;
  190.         fPushedChar = EOF;
  191.         }
  192.     else 
  193.         c= GetOneChar();
  194.          
  195.     switch ( c ) {
  196.     
  197.         case EOF:
  198.             fClass = tokEOF;
  199.             fMajor = 0;
  200.             return;
  201.         case tokBreakInData:
  202.             fClass= tokEOF;
  203.             fMajor= tokBreakInData;
  204.             return;
  205.             
  206.         case '\r': 
  207.         case '\n': //NEWLINE:
  208.             fClass = tokControl;
  209.             fMajor = tokNewline; //tokSpecialChar;
  210.             fMinor = c; //tokNewline;
  211.             return;
  212.              
  213.         default: 
  214.             fClass = tokText;
  215.             fMajor = c;
  216.             fMinor = c; // MapChar( c);
  217.             return; 
  218.             
  219.         }
  220. }
  221.  
  222.  
  223.  
  224. // static
  225. char* DRichprocess::gGenCharMap=  DRichprocess::ReadOutputMap("gen");
  226. char* DRichprocess::gSymCharMap=  DRichprocess::ReadOutputMap("sym");
  227.  
  228. char* DRichprocess::ReadOutputMap( char *file)
  229. {
  230. // from rtfmaps.h
  231. #ifdef WIN_MAC
  232. # define     genInMap  mac_gen_CharCode 
  233. # define     symInMap  mac_sym_CharCode 
  234. #else
  235. # define     genInMap  ansi_gen_CharCode 
  236. # define     symInMap  ansi_sym_CharCode 
  237. #endif
  238.     short *inMap, i, val;
  239.     char *outMap = (char*) MemNew( rtfSC_MaxChar*sizeof(char));
  240.     
  241.     if (*file == 's') inMap= symInMap;
  242.     else inMap= genInMap;
  243.  
  244.     for (i= 0; i<rtfSC_MaxChar; i++) outMap[i]= 0;
  245.     for (i= 255; i >= 0; i--) {
  246.         val= inMap[i];
  247.         if (val>=0 && val<rtfSC_MaxChar) outMap[val]= i;
  248.         }
  249.     return outMap;
  250. }
  251.  
  252.  
  253.  
  254. void DRichprocess::PutLitChar(short c)
  255. {
  256.     if (fTextSize >= fTextMax) {
  257.         fTextMax = fTextSize + 1024;
  258.         fText= (char*) MemMore( fText, fTextMax + 1);
  259.         }
  260.     fText[fTextSize++]= (char) c;
  261.     /* fText[fTextSize]= '\0'; */
  262. }
  263.  
  264. void DRichprocess::PutLitStr(char *s)
  265. {
  266.     long len = StrLen(s);
  267.     if (len + fTextSize >= fTextMax) {
  268.         fTextMax = fTextSize + len + 1024;
  269.         fText= (Nlm_CharPtr) MemMore( fText, fTextMax + 1);
  270.         }
  271.     Nlm_MemCopy( fText + fTextSize, s, len); /* +1 for nul */
  272.     fTextSize += len;
  273. }
  274.  
  275. void DRichprocess::PutLitCharWithStyle(short c)
  276. {
  277.     if (IsNewStyle()) StoreStyle(fOldStyleRec.style, FALSE);  
  278.     PutLitChar(c);
  279. }
  280.  
  281.  
  282.  
  283. void DRichprocess::PutStdChar( short stdCode)
  284. {
  285.     if (fOutMap) {
  286.         int och = fOutMap[stdCode];
  287.         if (och == rtfSC_nothing)    {  
  288.             char    buf[80];
  289.             sprintf(buf, "{{%s}}", RTFStdCharName(stdCode));
  290.             PutLitStr(buf);
  291.             }
  292.         else {
  293.             PutLitChar(och);
  294.             }
  295.         }
  296.     else {
  297.         PutLitChar(stdCode); 
  298.         }
  299. }
  300.  
  301.  
  302. void DRichprocess::PutStdCharWithStyle(short stdCode)
  303. {
  304.     if (IsNewStyle()) StoreStyle(fOldStyleRec.style, FALSE);  
  305.     PutStdChar(stdCode);
  306. }
  307.  
  308.  
  309. void DRichprocess::StoreStyle(DRichStyle& theStyle, Boolean force)
  310. {
  311.     if (force || fTextSize) {  
  312.         if (fStyleCount >= fStyleMax) {
  313.             fStyleMax  = fStyleCount + 10;
  314.             fStyleArray= (DRichStyle*) MemMore(fStyleArray, fStyleMax*sizeof(DRichStyle));
  315.             }
  316.     
  317.         theStyle.nextofs= fTextSize; //fLastTextSize;
  318.         //theStyle.textlen= fTextSize - fLastTextSize;
  319.         fLastTextSize= fTextSize;
  320.         if (!fFont) theStyle.font= GetNlmFont(); //x
  321.              
  322.         theStyle.last= FALSE; /* make sure... */
  323.         if (fStyleArray) fStyleArray[fStyleCount]= theStyle;
  324.         fStyleCount++; 
  325.          
  326.         //PutLitChar(chStyleTag);
  327.         }
  328.     fOldStyleRec= fStyleRec; /* gOldStyle= gStyle;  */
  329.     (void) GetNlmFont();          
  330.     NotNewStyle();
  331. }
  332.  
  333.  
  334. Boolean DRichprocess::IsNewStyle() 
  335. #if 1 //x
  336.     return fNewStyle; 
  337. #else
  338.     return TestNewStyle();
  339. #endif
  340. }
  341.  
  342. Boolean DRichprocess::TestNewStyle()
  343. {
  344.     fNewStyle = ( fOldStyleRec.fontname != fStyleRec.fontname 
  345.                     || fOldStyleRec.fontfamily != fStyleRec.fontfamily 
  346.                     || fOldStyleRec.fontsize != fStyleRec.fontsize 
  347.                     || fOldStyleRec.style.IsNotEqual( &fStyleRec.style)
  348.                     );
  349.     return fNewStyle;
  350. }
  351.  
  352.  
  353.  
  354. Nlm_FonT DRichprocess::GetNlmFont()
  355. {
  356. #if 1  //x
  357.         // GetFont is a time waster, cut down # of these calls !!
  358.     if (!fFont || IsNewStyle()) {
  359.         fFont= Nlm_GetFont( fStyleRec.fontname, fStyleRec.fontsize, 
  360.                     fStyleRec.style.bold, fStyleRec.style.italic, fStyleRec.style.underline != 0, 
  361.                     fStyleRec.fontfamily);
  362.         }
  363. #else
  364.         fFont= Nlm_GetFont( fStyleRec.fontname, fStyleRec.fontsize, 
  365.                     fStyleRec.style.bold, fStyleRec.style.italic, fStyleRec.style.underline != 0, 
  366.                     fStyleRec.fontfamily);
  367. #endif
  368.     fStyleRec.style.font= fFont;
  369.     fOldStyleRec= fStyleRec; 
  370.     NotNewStyle();
  371.     return fFont;
  372. }
  373.  
  374. void DRichprocess::PushStyle()
  375. {
  376.     if (fStyleStackSize<kMaxStyleStack) 
  377.         fStyleStack[fStyleStackSize++]= fStyleRec;
  378. }
  379.  
  380. void DRichprocess::PopStyle()
  381. {            
  382.     if (fStyleStackSize>0) 
  383.         fStyleRec= fStyleStack[--fStyleStackSize];
  384.     NewStyle();
  385. }
  386.  
  387.  
  388. void DRichprocess::DefaultParag()
  389. {
  390.     fParaFmt= fDefParaFmt;
  391. }
  392.  
  393. void DRichprocess::SetDefaultParag(DParagraph* theDefault)
  394. {
  395.     fDefParaFmt= *theDefault;
  396. }
  397.  
  398. void DRichprocess::DefaultStyle()
  399. {
  400.     fStyleRec= gDefaultStyle;
  401.     TestNewStyle();
  402. }
  403.  
  404.  
  405. void DRichprocess::NewParagraph()
  406. {
  407.     /* when new data forces use of new Dgg_ParData, 
  408.         append current text & para & col to growing doc */
  409. #if 1            
  410.     (void) GetNlmFont();  
  411.     StoreStyle( fStyleRec.style, TRUE);    /* gOldStyle */
  412.     //fTextSize--; /* unput last chStyleTag */
  413. #endif
  414.  
  415.     fStyleArray[fStyleCount-1].last= TRUE;
  416.     fText[fTextSize]= 0;
  417.     
  418.     fDoc->Append( fText, &fParaFmt, fStyleArray, fStyleCount);
  419.  
  420.     if (fProgress && fDataFile && (fParaCount % 10 == 0)) 
  421.         (void) Nlm_MonitorIntValue(fProgress, fDataFile->Tell());
  422.     fParaCount++;
  423.     fOldParaFmt= fParaFmt;
  424.     fParaFmt.numstops= fTextSize= fLastTextSize= fStyleCount= 0;
  425. }
  426.  
  427.  
  428.  
  429.  
  430.  
  431. void DRichprocess::handleUnknownClass()
  432. {
  433.     // nothing
  434. }
  435.  
  436. void DRichprocess::handleTextClass()
  437. {
  438.     if (IsNewStyle()) StoreStyle(fOldStyleRec.style, FALSE);  
  439.     PutLitChar(fMinor); 
  440.     fLastChar= fMajor;
  441. }
  442.  
  443. void DRichprocess::handleControlClass()
  444. {
  445.     switch (fMajor) {
  446.         
  447.         case tokNewline:
  448.             PutLitCharWithStyle ('\n');
  449.             NewParagraph();
  450.             break;
  451.  
  452.         default:
  453.             break;
  454.         }
  455.  
  456. }
  457.  
  458.  
  459.